home *** CD-ROM | disk | FTP | other *** search
/ Aminet 31 / Aminet 31 (1999)(Schatztruhe)[!][Jun 1999].iso / Aminet / dev / gui / gtlayout.lha / Source / LTP_LayoutGroup.c < prev    next >
C/C++ Source or Header  |  1998-09-09  |  17KB  |  723 lines

  1. /*
  2. **    GadTools layout toolkit
  3. **
  4. **    Copyright © 1993-1998 by Olaf `Olsen' Barthel
  5. **        Freely distributable.
  6. **
  7. **    :ts=4
  8. */
  9.  
  10. #ifndef _GTLAYOUT_GLOBAL_H
  11. #include "gtlayout_global.h"
  12. #endif
  13.  
  14. #include "Assert.h"
  15.  
  16. VOID
  17. LTP_LayoutGroup(LayoutHandle *Handle,ObjectNode *Group)
  18. {
  19.     if(!Handle->Failed)
  20.     {
  21.         ObjectNode    *Node;
  22.         ObjectNode    *ReturnKey;
  23.         ObjectNode    *EscKey;
  24.         ObjectNode    *CursorKey;
  25.         ObjectNode    *TabKey;
  26.         ObjectNode    *ActiveString;
  27.         LONG         Left;
  28.         LONG         Top;
  29.         LONG         Width;
  30.         LONG         Height;
  31.         LONG         MaxWidth;
  32.         LONG         MaxHeight;
  33.         BOOL         DefaultCorrection;
  34.  
  35.         Left                = 0;
  36.         Top                    = 0;
  37.  
  38.         ReturnKey            = NULL;
  39.         EscKey                = NULL;
  40.         CursorKey            = NULL;
  41.         TabKey                = NULL;
  42.         ActiveString        = NULL;
  43.         DefaultCorrection    = FALSE;
  44.         MaxWidth            = 0;
  45.         MaxHeight            = 0;
  46.  
  47.         SCANGROUP(Group,Node)
  48.         {
  49.             LTP_DetermineSize(Handle,Node);
  50.  
  51.             switch(Node->Type)
  52.             {
  53.                 case BUTTON_KIND:
  54.  
  55.                     if(Node->Special.Button.ReturnKey)
  56.                         ReturnKey = Node;
  57.                     else
  58.                     {
  59.                         if(Node->Special.Button.EscKey)
  60.                             EscKey = Node;
  61.                     }
  62.  
  63.                     DefaultCorrection |= Node->Special.Button.DefaultCorrection;
  64.  
  65.                     break;
  66.  
  67.                 case CYCLE_KIND:
  68.  
  69.                     if(Node->Special.Cycle.TabKey)
  70.                         TabKey = Node;
  71.  
  72.                     break;
  73.  
  74.                 #ifdef DO_POPUP_KIND
  75.                 {
  76.                     case POPUP_KIND:
  77.  
  78.                         if(Node->Special.Popup.TabKey)
  79.                             TabKey = Node;
  80.  
  81.                         break;
  82.                 }
  83.                 #endif
  84.  
  85.                 #ifdef DO_TAB_KIND
  86.                 {
  87.                     case TAB_KIND:
  88.  
  89.                         if(Node->Special.Tab.TabKey)
  90.                             TabKey = Node;
  91.  
  92.                         break;
  93.                 }
  94.                 #endif
  95.  
  96.                 case MX_KIND:
  97.  
  98.                     if(Node->Special.Radio.TabKey)
  99.                         TabKey = Node;
  100.  
  101.                     break;
  102.  
  103.                 case PASSWORD_KIND:
  104.                 case STRING_KIND:
  105.                 case FRACTION_KIND:
  106.  
  107.                     if(Node->Special.String.Activate)
  108.                         ActiveString = Node;
  109.  
  110.                     break;
  111.  
  112.                 case INTEGER_KIND:
  113.  
  114.                     if(Node->Special.Integer.Activate)
  115.                         ActiveString = Node;
  116.  
  117.                     break;
  118.  
  119.                 case LISTVIEW_KIND:
  120.  
  121.                     if(Node->Special.List.CursorKey)
  122.                         CursorKey = Node;
  123.  
  124.                     break;
  125.             }
  126.  
  127.             if(Node->Width > MaxWidth)
  128.                 MaxWidth = Node->Width;
  129.  
  130.             if(Node->Height > MaxHeight)
  131.                 MaxHeight = Node->Height;
  132.         }
  133.  
  134.         if(ReturnKey || DefaultCorrection)
  135.         {
  136.             SCANGROUP(Group,Node)
  137.             {
  138.                 #ifdef OLD_STYLE_DEFAULT_KEY
  139.                 {
  140.                     Node->GroupIndent = TRUE;
  141.  
  142.                     Node->Width        += 4 + 4;
  143.                     Node->Height    += 2 + 2;
  144.                 }
  145.                 #else
  146.                 {
  147.                     Node->Width        += 1 + 1;
  148.                     Node->Height    += 1 + 1;
  149.                 }
  150.                 #endif
  151.  
  152.                 if(Node->Width > MaxWidth)
  153.                     MaxWidth = Node->Width;
  154.  
  155.                 if(Node->Height > MaxHeight)
  156.                     MaxHeight = Node->Height;
  157.             }
  158.         }
  159.  
  160.         if(Group->Special.Group.SameSize)
  161.         {
  162.             SCANGROUP(Group,Node)
  163.             {
  164.                 if(Node->Width < MaxWidth && Node->Type != YBAR_KIND && Node->Type != CHECKBOX_KIND)
  165.                 {
  166.                     if(Node->Type == GROUP_KIND)
  167.                     {
  168.                         if(!Node->Special.Group.NoIndent)
  169.                         {
  170.                             if(Node->Special.Group.AlignRight)
  171.                                 Node->Special.Group.ExtraLeft += MaxWidth - Node->Width;
  172.                             else
  173.                                 Node->Special.Group.ExtraLeft += (MaxWidth - Node->Width) / 2;
  174.                         }
  175.                     }
  176.  
  177.                     Node->Width = MaxWidth;
  178.                 }
  179.  
  180.                 if(Node->Height < MaxHeight && Node->Type != XBAR_KIND && Node->Type != CHECKBOX_KIND)
  181.                 {
  182.                     if(Node->Type == GROUP_KIND && !Node->Special.Group.NoIndent)
  183.                         Node->Special.Group.ExtraTop += (MaxHeight - Node->Height) / 2;
  184.  
  185.                     Node->Height = MaxHeight;
  186.                 }
  187.             }
  188.         }
  189.  
  190.         if(Group->Special.Group.Horizontal)
  191.         {
  192.             LONG x,y,w,MaxTop = 0,MaxWidth = 0,MaxHeight = 0,Count = 0;
  193.  
  194.             if(Group->Node.mln_Pred->mln_Pred && Group->Special.Group.LastAttributes)
  195.             {
  196.                 ObjectNode *LastGroup = (ObjectNode *)Group->Node.mln_Pred;
  197.  
  198.                 MaxTop        = LastGroup->Special.Group.MaxOffset;
  199.                 MaxHeight    = LastGroup->Special.Group.MaxSize;
  200.             }
  201.  
  202.             SCANGROUP(Group,Node)
  203.             {
  204.                 if(!LIKE_STRING_KIND(Node) || Node->Special.String.LinkID == -1)
  205.                 {
  206.                     if(!Group->Special.Group.Paging && Count++)
  207.                     {
  208.                         if(Node->ExtraSpace > 0)
  209.                             x = Left + Node->ExtraSpace * Handle->InterWidth;
  210.                         else
  211.                         {
  212.                             if(Node->ExtraSpace < 0)
  213.                                 x = Left - Node->ExtraSpace;
  214.                             else
  215.                                 x = Left + Node->LayoutSpace * Handle->InterWidth;
  216.                         }
  217.                     }
  218.                     else
  219.                         x = Left;
  220.  
  221.                     y = Top;
  222.                     w = Node->Width;
  223.  
  224.                     switch(Node->LabelPlace)
  225.                     {
  226.                         case PLACE_LEFT:
  227.  
  228.                             if(Node->Type == MX_KIND)
  229.                             {
  230.                                 x += Node->Special.Radio.LabelWidth + INTERWIDTH;
  231.  
  232.                                 if(Node->Label)
  233.                                 {
  234.                                     if(Node->Special.Radio.TitlePlace == PLACETEXT_LEFT)
  235.                                         x += Node->LabelWidth + INTERWIDTH;
  236.                                     else
  237.                                         w += INTERWIDTH + Node->LabelWidth;
  238.                                 }
  239.                             }
  240.                             else
  241.                             {
  242.                                 if(Node->Label || (Node->Type == BOX_KIND && Node->Special.Box.Labels))
  243.                                     x += Node->LabelWidth + INTERWIDTH;
  244.                             }
  245.  
  246.                             break;
  247.  
  248.                         case PLACE_RIGHT:
  249.  
  250.                             if(Node->Type == MX_KIND)
  251.                             {
  252.                                 w += INTERWIDTH + Node->Special.Radio.LabelWidth;
  253.  
  254.                                 if(Node->Label)
  255.                                 {
  256.                                     if(Node->Special.Radio.TitlePlace == PLACETEXT_LEFT)
  257.                                         x += Node->LabelWidth + INTERWIDTH;
  258.                                     else
  259.                                         w += INTERWIDTH + Node->LabelWidth;
  260.                                 }
  261.                             }
  262.                             else
  263.                             {
  264.                                 if(Node->Label || (Node->Type == BOX_KIND && Node->Special.Box.Labels))
  265.                                     w += INTERWIDTH + Node->LabelWidth;
  266.                             }
  267.  
  268.                             break;
  269.  
  270.                         case PLACE_ABOVE:
  271.  
  272.                             if(Node->Label || (Node->Type == BOX_KIND && Node->Special.Box.Labels))
  273.                             {
  274.                                 if(Node->Type == LISTVIEW_KIND && Node->Special.List.TextAttr && Node->Special.List.FlushLabelLeft)
  275.                                     y += Node->Special.List.FixedGlyphHeight + INTERHEIGHT;
  276.                                 else
  277.                                     y += Handle->GlyphHeight + INTERHEIGHT;
  278.                             }
  279.  
  280.                             break;
  281.                     }
  282.  
  283.                     if(Node->Type == SLIDER_KIND)
  284.                     {
  285.                         if(Node->Special.Slider.LevelPlace == PLACETEXT_RIGHT && Node->Special.Slider.LevelFormat)
  286.                             w += INTERWIDTH + Node->Special.Slider.LevelWidth;
  287.  
  288.                         if(Node->Special.Slider.LevelPlace == PLACETEXT_LEFT && Node->LabelPlace != PLACE_LEFT && Node->Special.Slider.LevelFormat)
  289.                             x += INTERWIDTH + Node->Special.Slider.LevelWidth;
  290.                     }
  291.  
  292.                     #ifdef DO_LEVEL_KIND
  293.                     {
  294.                         if(Node->Type == LEVEL_KIND)
  295.                         {
  296.                             if(Node->Special.Level.LevelFormat != NULL)
  297.                             {
  298.                                 if(Node->Special.Level.LevelPlace == PLACETEXT_RIGHT)
  299.                                     w += INTERWIDTH + Node->Special.Level.MaxLevelWidth;
  300.  
  301.                                 if(Node->Special.Level.LevelPlace == PLACETEXT_LEFT && Node->LabelPlace != PLACE_LEFT)
  302.                                     x += INTERWIDTH + Node->Special.Level.MaxLevelWidth;
  303.                             }
  304.                         }
  305.                     }
  306.                     #endif    /* DO_LEVEL_KIND */
  307.  
  308.                     if(Node->Type == LISTVIEW_KIND && Node->Special.List.ExtraLabelWidth)
  309.                         x += Node->Special.List.ExtraLabelWidth + INTERWIDTH;
  310.  
  311.                     if(y > MaxTop)
  312.                         MaxTop = y;
  313.  
  314.                     if(Node->Height > MaxHeight)
  315.                         MaxHeight = Node->Height;
  316.  
  317.                     if(Node->LabelPlace == PLACE_BELOW && Node->Label)
  318.                     {
  319.                         LONG Height;
  320.  
  321.                         if(Node->Type == LISTVIEW_KIND && Node->Special.List.TextAttr && Node->Special.List.FlushLabelLeft)
  322.                             Height = Node->Height + INTERHEIGHT + Node->Special.List.FixedGlyphHeight;
  323.                         else
  324.                             Height = Node->Height + INTERHEIGHT + Handle->GlyphHeight;
  325.  
  326.                         if(Height > MaxHeight)
  327.                             MaxHeight = Height;
  328.                     }
  329.                     else
  330.                     {
  331.                         if(Node->Height > MaxHeight)
  332.                             MaxHeight = Node->Height;
  333.                     }
  334.  
  335.                     if(x + w > MaxWidth)
  336.                         MaxWidth = x+w;
  337.  
  338.                     Node->Left = x;
  339.  
  340.                     if(!Group->Special.Group.Paging)
  341.                         Left = x + w;
  342.                 }
  343.             }
  344.  
  345.             SCANGROUP(Group,Node)
  346.             {
  347.                 if(!LIKE_STRING_KIND(Node) || Node->Special.String.LinkID == -1)
  348.                 {
  349.                     Node->Top = MaxTop;
  350.  
  351.                     if(Node->Type == GROUP_KIND)
  352.                         Node->Special.Group.ExtraTop += MaxTop - Top;
  353.  
  354.                     if(Node->Height < MaxHeight)
  355.                     {
  356.                         register BOOL CanChangeHeight;
  357.  
  358.                         #ifdef DO_BOOPSI_KIND
  359.                         {
  360.                             CanChangeHeight = (BOOL)(    (Node->Type == PALETTE_KIND && !Node->Special.Palette.UsePicker) ||
  361.                                                         (Node->Type == LISTVIEW_KIND) ||
  362.                                                         (Node->Type == BOOPSI_KIND && !Node->Special.BOOPSI.ExactHeight)
  363.                                                     );
  364.                         }
  365.                         #else
  366.                         {
  367.                             CanChangeHeight = (BOOL)(    (Node->Type == PALETTE_KIND && !Node->Special.Palette.UsePicker) ||
  368.                                                         (Node->Type == LISTVIEW_KIND)
  369.                                                     );
  370.                         }
  371.                         #endif    /* DO_BOOPSI_KIND */
  372.  
  373.                         if(CanChangeHeight)
  374.                         {
  375.                             Node->Hei